#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "TcpServer.h"
#include "SharedMemoryIPC.h"
#include "protecol.h"
#include <thread>

void run()
{
    TcpServer *server = new TcpServer(8888, 4);
    server->run();
}
void initUserDate()
{
    CData::user_data = {
        {1, "user1", "123456", ":/image/image/1.jpg"},
        {2, "user2", "123456", ":/image/image/2.jpg"},
        {3, "user3", "123456", ":/image/image/3.jpg"}};
    cout << "初始化用户数据:" << CData::user_data.size() << endl;
}
int main(int argc, char *argv[])
{
    // initUserDate();
    // // 启动服务器
    // // 前置服务器
    // int pid = fork();
    // // 子进程
    // if (pid == 0)
    // {
    //     sleep(1);
    //     // 后置服务器
    //     // 这里主要是进行一个任务的处理，然后写入共享内存
    //     SharedMemoryIPC &shm=SharedMemoryIPC::getReaderInstance();
    //     char data[BLOCK_SIZE] = {0};
    //     char  buffer[1024]={0};
    //     HEAD head={0};
    //     char body[1024]={0};
    //     int fd=0;
    //     while (1)
    //     {
    //         shm.read_shm(data);
    //         memcpy(&fd,data,sizeof(int));
    //         memcpy(&head,data+sizeof(int),sizeof(HEAD));
    //         memcpy(body,data+sizeof(int)+sizeof(HEAD),head.data_len);
    //         cout<<"请求类型:"<<head.service_type<<endl;
    //         cout<<"客户端fd:"<<fd<<endl;

    //         SharedMemoryIPC&  shm2=SharedMemoryIPC::getWriterInstance(1002,2002,3002);
    //         shm2.write_shm(data);
    //         //这样不行，进程间的文件描述符是独立的
    //         // int size=read(atoi(data),buffer,sizeof(buffer));
    //         // if(size==0)
    //         // {
    //         //     cout<<"没有数据";
    //         // }
    //         // memcpy(&head,buffer,sizeof(HEAD));
    //         // memcpy(&body,buffer+sizeof(HEAD),head.data_len);
    //         // cout<<"head.service_type:"<<head.service_type<<endl;
    //         // cout<<"head.data_len:"<<head.data_len<<endl;

    //         // bzero(&head,sizeof(head));
    //         // bzero(body,sizeof(body));
    //         //读取到前置服务器发来的文件描述符，然后读文件描述符里面的内容，解析协议进行任务处理

    //         bzero(data, sizeof(data));
    //     }
    // }
    // else if (pid > 0) // 父进程
    // {
    //     // 前置服务器
    //     // 进行数据的接收，然后写入到共享内存，让后置服务器处理

    //     thread server_thread(run);

    //     SharedMemoryIPC&shm=SharedMemoryIPC::getReaderInstance(1002,2002,3002);
    //      char  buffer[1024]={0};
    //     char data[BLOCK_SIZE] = {0};
    //     HEAD head={0};
    //     char body[1024]={0};
    //     int fd=0;

    //     while(1)
    //     {
    //         shm.read_shm(data);
    //         memcpy(&fd,data,sizeof(int));
    //         memcpy(&head,data+sizeof(int),sizeof(HEAD));
    //         memcpy(body,data+sizeof(int)+sizeof(HEAD),head.data_len);
    //         cout<<"回复的请求类型:"<<head.service_type<<endl;
    //         cout<<"回复的客户端fd:"<<fd<<endl;
    //     }

    //     server_thread.join();

    // }

    thread server_thread(run);
    SharedMemoryIPC&write_shm=SharedMemoryIPC::getWriterInstance();
    SharedMemoryIPC &shm = SharedMemoryIPC::getReaderInstance(1002, 2002, 3002);
    char buffer[1024] = {0};
    char data[BLOCK_SIZE] = {0};
    HEAD head = {0};
    char body[1024] = {0};
    int fd = 0;

    while (1)
    {
        shm.read_shm(data);
        memcpy(&fd, data, sizeof(int));
        memcpy(&head, data + sizeof(int), sizeof(HEAD));
        memcpy(body, data + sizeof(int) + sizeof(HEAD), head.data_len);
        cout << "回复的请求类型:" << head.service_type << endl;
        cout<<"回复的请求长度:"<<head.data_len<<endl;
        cout << "回复的客户端fd:" << fd << endl;

        if(head.service_type==FRIEND)
        {
            FRI_RESP fri_resp;
            memcpy(&fri_resp,body,sizeof(FRI_RESP));
            cout<<"用户数量:"<<fri_resp.num<<endl;
            cout<<"第一个用户的路径"<<fri_resp.users[0].getIcon()<<endl;
            cout<<"数据大小:"<<sizeof(fri_resp)<<endl;
        }

        //发送给客户端
        memcpy(buffer, &head, sizeof(HEAD));
        memcpy(buffer + sizeof(HEAD), body, head.data_len);
        write(fd, buffer, sizeof(HEAD) + head.data_len);
    }

    server_thread.join();

    return 0;
}